﻿//Copyright (C) 2009  Jaco (ScionBot.com)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Scion.Library;

namespace Scion.Core
{
    /// <summary>
    /// The core of the bot. In essence, the bot first gets initialized and started here. All API functions
    /// pull information from this class.
    /// </summary>
    public class Stub
    {
        //Super/bot # objects.
        public Bot bot;
        public int botNumber = 0;
        public int port;
        //Bot parts objects.
        public Reflection botReflection;
        public Loader botLoader;
        public Offscreen botOffscreen;
        public GFX botGraphics;
        public Account botAccount;
        public Bridge botBridge;
        public Script botScript;
        public Random botRandom;
        public Canvas botCanvas;
        public Log botLog;
        //Script access objects.
        public Mouse mouse;
        public Keyboard keyboard;

        public Stub(Bot b, int number, int portNumber, Account account)
        {
            bot = b;
            botNumber = number;
            botAccount = account;
            port = portNumber;
        }

        public bool Start()
        {
            botLoader = new Loader(this);
            botOffscreen = new Offscreen(this);
            botBridge = new Bridge(this);
            botGraphics = new GFX(this);
            mouse = new Mouse(this);
            keyboard = new Keyboard(this);
            botRandom = new Random(this);
            botCanvas = new Canvas(this);
            botLog = new Log(this);
            botReflection = new Reflection(this);
            botScript = new Script(this, "temp");
            //Load the bot into a process.
            botLoader.Load();
            //Set the window attributes for a offscreen capturing process.
            botOffscreen.GetHandle();
            botOffscreen.ShowWindow(false);
            botOffscreen.ApplyImmunity();
            botOffscreen.TransparentWindow(true);
            botOffscreen.UpdateWindow();
            botOffscreen.ShowWindow(true);
            botAccount.PushStub(this);
            botRandom.GetRandomDlls();
            return true;
        }

        public bool Stop()
        {
            //Try and kill the botProcess. If it cannot, it is already killed.
            try
            {
                botLoader.botProcess.Kill();
            }
            catch
            {
            }
            //Dispose all the free memory.
            botLoader.botProcess.Dispose();
            botLoader.botInput.Dispose();
            botLoader.botOutput.Dispose();
            botLog.logStream.Dispose();
            botLog.logStreamReader.Dispose();
            botLog.logStreamWriter.Dispose();
            try
            {
                if (botScript != null)
                    botScript.Terminate();
            }
            catch
            {
            }
            //TODO: Add more
            //Do a garbage collection to clean-up the remainder.
            GC.Collect();
            return true;
        }

        public void ExecuteScript(string scrName)
        {
            botScript = new Script(this, scrName);
            botScript.Start();
        }
    }
}
